
import 'dart:ui';

import 'package:flame/components.dart';
import 'package:klondike/klondike/klondike_game.dart';
import 'package:klondike/klondike/klondike_world.dart';

import '../../enums/suit.dart';
import '../../components/pile.dart';
import '../../components/card.dart';
import 'tableau_pile.dart';

class FoundationPile
  extends PositionComponent
  with HasWorldReference<KlondikeWorld>
  implements Pile {

  FoundationPile(int intSuit, this.checkWin, {super.position})
    : suit = Suit.fromInt(intSuit),
      super(size: KlondikeGame.cardSize);

  final List<Card> _cards = [];
  final Suit suit;

  final VoidCallback checkWin;

  final _borderPaint = Paint()
    ..style = PaintingStyle.stroke
    ..strokeWidth = 10
    ..color = const Color(0x50ffffff);
  
  late final _suitPaint = Paint()
    ..color = suit.isRed? const Color(0x3a000000) : const Color(0x64000000)
    ..blendMode = BlendMode.luminosity;

  bool get isFull => _cards.length == 13;

  @override
  void render(Canvas canvas) {
    canvas.drawRRect(KlondikeGame.cardRRect, _borderPaint);
    suit.sprite.render(canvas,
      position: size / 2,
      anchor: Anchor.center,
      size: Vector2.all(KlondikeGame.cardWidth * 0.6),
      overridePaint: _suitPaint,
    );
  }
  
  @override
  bool canMoveCard(List<Card> cards) {
    assert(cards.length == 1);
    Card card = cards.first;

    return _cards.isNotEmpty && card == _cards.last;
  }

  @override
  bool canAcceptCard(List<Card> cards) {
    if(cards.length != 1) {
      return false;
    }

    Card card = cards.first;

    final topCardRank = _cards.isEmpty? 0 : _cards.last.rank.value;
    return card.suit == suit 
      && card.rank.value == topCardRank + 1;
  }

  @override
  void removeCard(List<Card> cards) {
    assert(canMoveCard(cards));
    _cards.removeLast();
  }

  @override
  void acquireCard(List<Card> cards) {
    assert(cards.length == 1);
    Card card = cards.first;
    
    assert(card.isFaceUp);
    card.position = position;
    card.priority = _cards.length;
    _cards.add(card);
    card.pile = this;
    if(isFull) {
      checkWin();
    }
  }
  
  @override
  void returnCard(List<Card> cards) {
    assert(cards.length == 1);
    Card card = cards.first;
    
    card.position = position;
    card.priority = _cards.indexOf(card);
  }

  @override
  PositionComponent top() => _cards.isNotEmpty ? _cards.last : this;

  @override void handleTapUp(Card card) {}

  @override
  Future<bool> tryToMove() async {

    if(_cards.isEmpty) {
      return false;
    }

    List<Card> singleCard = [_cards.last];

    
    if(canMoveCard(singleCard)) {
      for(TableauPile tableauPile in world.tableauPiles) {
        if(tableauPile == this) {
          continue;
        }

        if(tableauPile.canAcceptCard(singleCard)) {
          await world.highlight(singleCard, [tableauPile.top()]);
          return true;
        }
      }
    }

    return false;
  }
}